home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2004 #9 / Amiga Plus CD - 2004 - No. 09.iso / amigaplus / tools / dev_libs / feelin040718 / demos / class3.c < prev    next >
C/C++ Source or Header  |  2004-08-03  |  8KB  |  285 lines

  1. ;/*
  2.    F_Create.rexx EXE Class3
  3.    QUIT
  4.    _________________________________________________________________________
  5.  
  6.    Class3 Demo © 2000-2004 by Olivier LAVIALE <gofromiel@numericable.com>
  7. */
  8.  
  9. #include <intuition/intuition.h>
  10. #include <libraries/feelin.h>
  11.  
  12. #include <proto/exec.h>
  13. #include <proto/dos.h>
  14. #include <proto/graphics.h>
  15. #include <proto/feelin.h>
  16.  
  17. struct  FeelinBase    *FeelinBase;
  18.  
  19. // This is the instance data for our custom class.
  20.  
  21. struct LocalObjectData
  22. {
  23.    FAreaData                       *AreaData;
  24.    WORD                             x,y, sx,sy;
  25. };
  26.  
  27. ///mNew
  28. F_METHOD(ULONG,mNew)
  29. {
  30.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  31.  
  32.    LOD -> AreaData = (FAreaData *) F_Get(Obj,FA_AreaData);
  33.  
  34.    return F_SUPERDO();
  35. }
  36. //+
  37. /// mSetup
  38. /*
  39.    FC_Area creates a struct FeelinEventHandler on  the  fly  depending  the
  40.    events  modified  by the FM_ModifyHandler method. Using FM_ModifyHandler
  41.    it's a piece of cake ot request IDCMP events.
  42. */
  43. F_METHOD(ULONG,mSetup)
  44. {
  45.    F_Do(Obj,FM_ModifyHandler,IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,0);
  46.  
  47.    return F_SUPERDO();
  48. }
  49. //+
  50. /// mCleanup
  51. /*
  52.    FC_Area creates a struct FeelinEventHandler on  the  fly  depending  the
  53.    events  modified  by the FM_ModifyHandler method. Using FM_ModifyHandler
  54.    it's a piece of cake ot request IDCMP events.
  55. */
  56. F_METHOD(ULONG,mCleanup)
  57. {
  58.    F_Do(Obj,FM_ModifyHandler,0,IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS);
  59.  
  60.    return F_SUPERDO();
  61. }
  62. //+
  63. /// mAskMinMax
  64. /*
  65.    FM_AskMinMax will be called before the window is opened. We need to tell
  66.    the FC_Window object the minimum and maximum size of our object.
  67.  
  68.    When you are the first receiving  the  method  the  fields  _minw()  and
  69.    _minh() are set to zero and the fields _maxw() and _maxh() to FV_MAXMAX.
  70.    We can add values to _minw() and _minh() or set _maxw() and  _maxh()  if
  71.    we need to. Then we pass the method to our superclass.
  72.  
  73.    When the method reaches FC_Area these values will be adjusted  according
  74.    to FA_MinXxx, FA_FixedXxx and FA_FixXxx attributes.
  75. */
  76.  
  77. F_METHOD(ULONG,mAskMinMax)
  78. {
  79.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  80.  
  81.    _minw += 100; _minh += 040;
  82.    _maxw  = 500; _maxh  = 300;
  83.  
  84.    return F_SUPERDO();
  85. }
  86. //+
  87. /// mDraw
  88. /*
  89.    Draw method is called whenever Feelin feels (obviously  ;-))  we  should
  90.    render  our object. This usually happens after layout is finished. Note:
  91.    You may only render within the rectangle _mx(), _my(), _mx2(), _my2().
  92. */
  93. F_METHODM(void,mDraw,FS_Draw)
  94. {
  95.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  96.    struct RastPort *rp         = _rp;
  97.  
  98. /*
  99.    Let our superclass draw itself first, FC_Area would e.g. draw the  frame
  100.    and clear the whole region. What it does exactly depends on flags.
  101. */
  102.  
  103.    F_SUPERDO();
  104.  
  105. /*
  106.    IF FF_Draw_Object isn't set, we shouldn't  draw  anything.  Feelin  just
  107.    wanted to update the frame or something like that.
  108. */
  109.  
  110.    if (Msg -> Flags & FF_Draw_Update) // called from our input method
  111.    {
  112.       if (LOD -> sx || LOD -> sy)
  113.       {
  114.          _BPen(_pens[FV_Pen_Shine]);
  115.          ScrollRaster(rp,LOD -> sx,LOD -> sy,_mx,_my,_mx2,_my2);
  116.          _BPen(_pens[FV_Pen_Dark]);
  117.          LOD -> sx = 0;
  118.          LOD -> sy = 0;
  119.       }
  120.       else
  121.       {
  122.          _APen(_pens[FV_Pen_Shadow]);
  123.          _Plot(LOD -> x,LOD -> y);
  124.       }
  125.    }
  126.    else if (Msg -> Flags & FF_Draw_Object)
  127.    {
  128.       _APen(_pens[FV_Pen_Shine]);
  129.       _Boxf(_mx,_my,_mx2,_my2);
  130.    }
  131. }
  132. //+
  133. ///mHandleEvent
  134. /*
  135. in mSetup() we said that we want get a  message  if  mousebuttons  or  keys
  136. pressed so we have to define the input-handler
  137.  
  138. Note :
  139.  
  140.    This is really a good example, because it  shows  how  to  use  critical
  141.    events carefully:
  142.  
  143.    IDCMP_MOUSEMOVE is only needed when left-mousebutton is pressed,  so  we
  144.    dont  request  this  until  we  get  a  SELECTDOWN-message and we reject
  145.    IDCMP_MOUSEMOVE immeditly after we get a SELECTUP-message
  146. */
  147.  
  148. F_METHODM(ULONG,mHandleEvent,FS_HandleEvent)
  149. {
  150.    #define _between(a,x,b) ((x) >= (a) && (x) <= (b))
  151.    #define _isinobject(x,y) (_between(_mx,(x),_mx2) && _between(_my,(y),_my2))
  152.  
  153. /*
  154. Note on Arrows handling :
  155.  
  156. If you don't handle arrows return NULL, this will allow  Window  object  to
  157. cycle   through  its  chain  using  arrows  instead  of  tabulations  (more
  158. confortable hu ?), else return FF_HandleEvent_Eat as usual.
  159. */
  160.  
  161.    struct LocalObjectData *LOD = F_LOD(Class,Obj);
  162.    struct FeelinEvent     *FEv = Msg -> FEv;
  163.  
  164.    if (FEv -> Key)
  165.    {
  166.       switch (FEv -> Key)
  167.       {
  168.          case FV_KEY_LEFT:  LOD -> sx = -1; break;
  169.          case FV_KEY_RIGHT: LOD -> sx =  1; break;
  170.          case FV_KEY_UP:    LOD -> sy = -1; break;
  171.          case FV_KEY_DOWN:  LOD -> sy =  1; break;
  172.          default:           return NULL;
  173.       }
  174.  
  175.       F_Draw(Obj,FF_Draw_Update);
  176.  
  177.       return FF_HandleEvent_Eat; // Forbid arrow cycling, because *WE* handle key events.
  178.    }
  179.    else if (FEv -> Class == IDCMP_MOUSEBUTTONS)
  180.    {
  181.       if (FEv -> Code == SELECTDOWN)
  182.       {
  183.          if (_isinobject(FEv -> MouseX,FEv -> MouseY))
  184.          {
  185.             LOD -> x = FEv -> MouseX;
  186.             LOD -> y = FEv -> MouseY;
  187.             F_Draw(Obj,FF_Draw_Update);
  188.             // Only request IDCMP_MOUSEMOVE if we realy need it
  189.             F_Do(Obj,FM_ModifyHandler,IDCMP_MOUSEMOVE,0);
  190.  
  191.             return FF_HandleEvent_Eat;
  192.          }
  193.       }
  194.       else
  195.       {
  196.          // Reject IDCMP_MOUSEMOVE because lmb is no longer pressed
  197.          F_Do(Obj,FM_ModifyHandler,0,IDCMP_MOUSEMOVE);
  198.       }
  199.    }
  200.    else if (FEv -> Class == IDCMP_MOUSEMOVE)
  201.    {
  202.       if (_isinobject(FEv -> MouseX,FEv -> MouseY))
  203.       {
  204.          LOD -> x = FEv -> MouseX;
  205.          LOD -> y = FEv -> MouseY;
  206.  
  207.          F_Draw(Obj,FF_Draw_Update);
  208.  
  209.          return FF_HandleEvent_Eat;
  210.       }
  211.    }
  212.    return NULL;
  213. }
  214. //+
  215.  
  216. /// Main
  217. void main()
  218. {
  219.    APTR app,win,myobj;
  220.    struct FeelinClass *cc;
  221.  
  222.    static struct FeelinMethodEntry Handlers[] =
  223.    {
  224.       (FMethod) mNew,         NULL, FM_New,
  225.       (FMethod) mSetup,       NULL, FM_Setup,
  226.       (FMethod) mCleanup,     NULL, FM_Cleanup,
  227.       (FMethod) mAskMinMax,   NULL, FM_AskMinMax,
  228.       (FMethod) mDraw,        NULL, FM_Draw,
  229.       (FMethod) mHandleEvent, NULL, FM_HandleEvent,
  230.        NULL
  231.    };
  232.  
  233.    if (FeelinBase = (APTR) OpenLibrary("feelin.library",FV_VERSION))
  234.    {
  235. /*
  236. Create the new custom class with a call to F_CreateClassA().
  237.  
  238. This function returns a feelinClass structure. You must use Class  ->  Name
  239. to  create  instance  of your custom class. This Name is unique and made by
  240. F_CreateClassA() when FA_Class_Name is NULL.
  241. */
  242.  
  243.       if (cc = F_CreateClass(FA_Class_Super,          FC_Area,
  244.                              FA_Class_LODSize,        sizeof (struct LocalObjectData),
  245.                              FA_Class_MethodsTable,   Handlers,
  246.                              TAG_DONE))
  247.       {
  248.          app = AppObject,
  249.             Child, win = WindowObject,
  250.                FA_ID,            MAKE_ID('M','A','I','N'),
  251.                FA_Window_Title, "A rather complex custom class",
  252.                FA_Window_Open,   TRUE,
  253.  
  254.                Child, VGroup,
  255.                   Child, TextObject, FA_SetMax,FV_SetMaxH, DontChain, TextFrame, TextBack, FA_Text, "<align=center><i>Paint</i> with <b>mouse</b>,<br><i>Scroll</i> with <b>cursor keys</b>.", End,
  256.                   Child, myobj = F_NewObj(cc -> Name, TextFrame, TAG_DONE),
  257.                End,
  258.  
  259.                FA_Window_ActiveObject, myobj, // Safe here
  260.             End,
  261.          End;
  262.  
  263.          if (app)
  264.          {
  265.             F_Do(win,FM_Notify,FA_Window_CloseRequest,TRUE, app,FM_Application_Shutdown,0);
  266.             F_Do(app,FM_Application_Run);
  267.             F_DisposeObj(app);
  268.          }
  269.  
  270.          F_DeleteClass(cc);
  271.       }
  272.       else
  273.       {
  274.          Printf("Could not create custom class.\n");
  275.       }
  276.  
  277.       CloseLibrary(FeelinBase);
  278.    }
  279.    else
  280.    {
  281.       Printf("Failed to open feelin.library\n");
  282.    }
  283. }
  284. //+
  285.